﻿import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Item {
    id: control

    property alias model                        : listView.model   // model
    property bool singleSelectionMode           : true             // 单选或多选模式选择
    property int itemHeight                     : 50               // 条目高度
    property color normalColor                  : "white"          // 条目未选择时的背景颜色
    property color hoverColor                   : "#F5F5F5"        // 条目未选择时鼠标移入的背景色
    property color selectedColor                : "#4CAF50"        // 条目选中后的背景颜色和选择器选中时的字体颜色
    property color selectedHoverColor           : "#43A047"        // 条目选择后鼠标移入条目后的背景颜色
    property color textColor                    : "black"          // 未选中时文本颜色
    property color selectedTextColor            : "white"          // 条目选中后的文本颜色
    property string displayRole                 : "name"           // model对象中的显示键值 -> model["name"]
    property string displayIsFile               : "isfile"         // model对象中的显示键值 -> model["isfile"]
    property bool showStatusBar                 : false            // 是否展示底部显示状态栏
    property real diameter                      : 15               // 选中指示器直径
    property real statusBarHeight               : 40               // 状态栏高度

    // signal
    signal itemSelected(int index, bool selected)
    signal selectionChanged(var selectedIndices)
    signal rightClicked(var mouse)

    // method
    function clearSelection() {
        internal.clearAllSelections()
    }
    function selectAll() {
        internal.selectAllItems()
    }
    function getSelectedIndices() {
        return internal.getSelectedItems(true)
    }
    function getSelectedItems() {
        return internal.getSelectedItems(false)
    }
    function addItem(itemData) {
        internal.addItemToList(itemData)
    }

    ListModel {
        id: listModel
        ListElement { name: "Item 1"; selected: false; isfile: false }
        ListElement { name: "Item 2"; selected: false; isfile: true  }
        ListElement { name: "Item 3"; selected: false; isfile: false }
        ListElement { name: "Item 4"; selected:  true; isfile: false }
    }

    QtObject {
        id: internal

        property string selectionRole           : "selected"
        property string isfileRole              : "isfile"
        function clearAllSelections() {
            for (var i = 0; i < listView.model.count; i++) {
                if (listView.model.get(i)[internal.selectionRole]) {
                    listView.model.setProperty(i, internal.selectionRole, false)
                }
            }
            control.selectionChanged([])
            statusBarAnimation.start()
        }
        function selectAllItems() {
            for (var i = 0; i < listView.model.count; i++) {
                if (!listView.model.get(i)[internal.selectionRole]) {
                    listView.model.setProperty(i, internal.selectionRole, true)
                }
            }
            control.selectionChanged(internal.getSelectedItems(true))
            statusBarAnimation.start()
        }
        function getSelectedItems(returnIndices) {
            var result = []
            for (var i = 0; i < listView.model.count; i++) {
                var item = listView.model.get(i)
                if (item[internal.selectionRole]) {
                    if (returnIndices) {
                        result.push(i)
                    } else {
                        result.push(item)
                    }
                }
            }
            return result
        }
        function addItemToList(itemData) {
            if (!itemData.hasOwnProperty(internal.selectionRole)) {
                itemData[internal.selectionRole] = false
            }
            listView.model.append(itemData)
        }
        function handleLeftClick(index) {
            var item = listView.model.get(index)
            var newSelectedState = !item[internal.selectionRole]
            if (control.singleSelectionMode) {
                // 单选模式 - 取消之前的选择
                for (var i = 0; i < listView.model.count; i++) {
                    if (i !== index && listView.model.get(i)[internal.selectionRole]) {
                        listView.model.setProperty(i, internal.selectionRole, false)
                        control.itemSelected(i, false)
                    }
                }
            }
            listView.model.setProperty(index, internal.selectionRole, newSelectedState)
            control.itemSelected(index, newSelectedState)
            control.selectionChanged(internal.getSelectedItems(true))
            statusBarAnimation.start()
        }
    }

    Column {
        anchors.fill                            : parent
        spacing                                 : 2
        anchors.margins                         : 3

        // 列表视图外层的鼠标区域，用于捕获整个列表区域的右键点击
        MouseArea {
            id: listContainerArea
            width                               : parent.width
            height                              : showStatusBar ? parent.height - control.statusBarHeight : parent.height
            acceptedButtons                     : Qt.RightButton

            // 鼠标右键点击
            onClicked                           : (mouse) => {
                control.rightClicked(mouse)
                contextMenu.popup()
            }

            ListView {
                id: listView
                width                           : parent.width
                height                          : parent.height
                clip                            : true
                spacing                         : 3
                model                           : listModel

                delegate                        : Rectangle {
                    id: delegateItem
                    width                       : listView.width
                    height                      : control.itemHeight
                    border.color                : "#CCCCCC"
                    radius                      : 4

                    // 动态计算背景色
                    color                       : {
                        if (model[internal.selectionRole]) {
                            return itemMouseArea.containsMouse ? control.selectedHoverColor : control.selectedColor
                        } else {
                            return itemMouseArea.containsMouse ? control.hoverColor : control.normalColor
                        }
                    }
                    // 背景色变动画
                    Behavior on color {
                        ColorAnimation { duration: 200 }
                    }

                    // 按下时的缩放效果
                    scale                       : itemMouseArea.pressed ? 0.98 : 1.0
                    Behavior on scale {
                        NumberAnimation { duration: 100 }
                    }

                    // Item Content
                    RowLayout {
                        anchors.fill: parent
                        spacing: 5
                        // Icon
                        Image {
                            source              : model[control.displayIsFile] ? "qrc:/res/image/file.png" : "qrc:/res/image/folder.png"
                            sourceSize.width    : control.diameter
                            sourceSize.height   : control.diameter
                            Layout.preferredWidth : control.diameter
                            Layout.preferredHeight: control.diameter
                            Layout.leftMargin   : 6
                        }
                        // 内容文本
                        Text {
                            id: id_text__item
                            Layout.fillWidth    : true
                            text                : model[control.displayRole] || ""
                            font.pixelSize      : 14
                            clip                : true
                            elide               : Text.ElideRight
                            color               : model[internal.selectionRole] ? control.selectedTextColor : control.textColor
                            Behavior on color {
                                ColorAnimation { duration: 200 }
                            }
                            TextMetrics {
                                id: textMetrics
                                font            : id_text__item.font
                                text            : id_text__item.text
                            }
                            ToolTip {
                                id: id_tooltip
                                text            : id_text__item.text
                                delay           : 1000
                                visible         : {
                                    if (id_text__item.text === "") {
                                        return false
                                    }
                                    // 如果文本显示内容超出了Text的范围，则通过ToolTip临时显示实际文本
                                    return (textMetrics.width > id_text__item.width) && itemMouseArea.containsMouse
                                }
                            }
                        }
                        // TODO 选中指示器
                        Rectangle {
                            id: checkIndicator
                            width               : control.diameter // 20
                            height              : control.diameter // 20
                            Layout.preferredWidth : control.diameter
                            Layout.preferredHeight: control.diameter
                            Layout.rightMargin  : 6
                            visible             : model[internal.selectionRole]
                            radius              : 10
                            color               : "white"
                            opacity             : model[internal.selectionRole] ? 1.0 : 0.0
                            Behavior on opacity {
                                NumberAnimation { duration: 200 }
                            }
                            scale               : model[internal.selectionRole] ? 1.0 : 0.5
                            Behavior on scale {
                                NumberAnimation { duration: 300; easing.type: Easing.OutBack }
                            }
                            Text {
                                anchors.centerIn: parent
                                text            : "✓" //"√"
                                color           : control.selectedColor
                                font.bold       : true
                            }
                        }
                    }

                    // 列表项的鼠标区域（只处理左右键）
                    MouseArea {
                        id: itemMouseArea
                        anchors.fill            : parent
                        hoverEnabled            : true
                        acceptedButtons         : Qt.LeftButton | Qt.RightButton
                        propagateComposedEvents : true // 与mouse.accepted配合后可将点击事件传递给上一级的MouseArea
                        onClicked: (mouse) => {
                            mouse.accepted = false // 不拦截鼠标事件
                            if (mouse.button === Qt.LeftButton || mouse.button === Qt.RightButton) {
                                if (model[internal.isfileRole]) {
                                    internal.handleLeftClick(index)
                                }
                            }
                        }
                        onDoubleClicked: {
                            if (!model[internal.isfileRole]) {
                                console.log("onDoubleClicked Folder: " + model[control.displayRole])
                            }
                        }
                    }
                } /* delegateItem */
            }
        }

        // 状态栏
        Rectangle {
            id: statusBar
            visible                             : control.showStatusBar
            width                               : parent.width
            height                              : control.statusBarHeight
            color                               : "#EEEEEE"
            Text {
                id: statusText
                anchors.centerIn                : parent
                font.bold                       : true
                text                            : {
                    var count = internal.getSelectedItems(true).length
                    return "Selected: " + count + " items" +
                           (control.singleSelectionMode ? " (Single Selection Mode)" : " (Multiple Selection Mode)")
                }
            }
        }

    }

    // 状态栏动画
    SequentialAnimation {
        id: statusBarAnimation
        PropertyAnimation {
            target                              : statusBar
            property                            : "color"
            to                                  : "#E3F2FD"
            duration                            : 200
        }
        PropertyAnimation {
            target                              : statusBar
            property                            : "color"
            to                                  : "#EEEEEE"
            duration                            : 300
        }
    }

    // 右键菜单
    Menu {
        id: contextMenu
        MenuItem {
            text                                : "清除选择"
            onTriggered                         : control.clearSelection()
        }
        MenuItem {
            text                                : "全部选择"
            onTriggered                         : control.selectAll()
        }
    }
    // 点击菜单外部关闭菜单
    MouseArea {
        anchors.fill                            : parent
        enabled                                 : contextMenu.visible
        onClicked                               : contextMenu.close()
        z                                       : -1
    }
}
